﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace MetaDrive.Core
{
    public abstract class FluentSpecification<T> : Specification<T>
    {
        protected Expression<Func<T, bool>> CurrentExpression { get; private set; }

        protected void AddExpression(Expression<Func<T, bool>> expression)
        {
            if (CurrentExpression == null)
                 CurrentExpression = expression;
            else CurrentExpression = ConcatenateExpressions(expression);
        }

        private Expression<Func<T, bool>> ConcatenateExpressions(Expression<Func<T, bool>> rightSide)
        {
            InvocationExpression rightSideInvoke = Expression.Invoke(rightSide, CurrentExpression.Parameters.Cast<Expression>());
            BinaryExpression binaryExpression = Expression.MakeBinary(ExpressionType.AndAlso, CurrentExpression.Body, rightSideInvoke);
            return Expression.Lambda<Func<T, bool>>(binaryExpression, CurrentExpression.Parameters);
        }

        public override bool IsSatisfiedBy(T element)
        {
            return CurrentExpression.Compile().Invoke(element);
        }
    }
}
